/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package in.jquickfinder.mainwindow;

import in.jquickfinder.extensiondomain.FileExtension;
import in.jquickfinder.filesearch.SearchFileRecursive;
import in.jquickfinder.models.CustomizedTableModel;
import in.jquickfinder.models.TablePopupListener;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.RowSorter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.TableModel;
import org.openide.util.LookupEvent;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.Lookup.Result;
import org.openide.util.LookupListener;
import org.openide.util.Utilities;
import org.openide.windows.WindowManager;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//in.jquickfinder.mainwindow//MainWindow//EN",
autostore = false)
@TopComponent.Description(preferredID = "MainWindowTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "in.jquickfinder.mainwindow.MainWindowTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_MainWindowAction",
preferredID = "MainWindowTopComponent")
public final class MainWindowTopComponent extends TopComponent implements ActionListener, LookupListener {

    private static MainWindowTopComponent instance;
    private static final String PREFERRED_ID = "MainWindowTopComponent";
    private Result<FileExtension> lookupResult;
    private JFileChooser fileChooser;
    private Collection searchFiles;
    private CustomizedTableModel tableModel;
    private ArrayList<File> fileList = new ArrayList<File>();
    private ArrayList<File> filteredFileList = new ArrayList<File>();

    public MainWindowTopComponent() {
        initComponents();
        setName(NbBundle.getMessage(MainWindowTopComponent.class, "CTL_MainWindowTopComponent"));
        setToolTipText(NbBundle.getMessage(MainWindowTopComponent.class, "HINT_MainWindowTopComponent"));
        initFileChooser();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        rowSorterToStringConverter1 = new in.jquickfinder.models.RowSorterToStringConverter();
        pathPanel = new javax.swing.JPanel();
        directoryPathLabel = new javax.swing.JLabel();
        directoryPathTextField = new javax.swing.JTextField();
        browseButton = new javax.swing.JButton();
        searchFileTextField = new javax.swing.JTextField();
        searchFileLabel = new javax.swing.JLabel();
        fileTablePanel = new javax.swing.JPanel();
        fileTableScrollPane = new javax.swing.JScrollPane();
        fileTable = new javax.swing.JTable();
        statusPanel = new javax.swing.JPanel();
        totalFilesLabel = new javax.swing.JLabel();
        secondsLabel = new javax.swing.JLabel();

        rowSorterToStringConverter1.setTable(fileTable);

        pathPanel.setLayout(null);

        directoryPathLabel.setFont(new java.awt.Font("Tahoma", 1, 11));
        org.openide.awt.Mnemonics.setLocalizedText(directoryPathLabel, org.openide.util.NbBundle.getMessage(MainWindowTopComponent.class, "MainWindowTopComponent.directoryPathLabel.text")); // NOI18N
        pathPanel.add(directoryPathLabel);
        directoryPathLabel.setBounds(10, 20, 30, 14);

        directoryPathTextField.setEditable(false);
        directoryPathTextField.setFont(new java.awt.Font("Tahoma", 1, 11));
        pathPanel.add(directoryPathTextField);
        directoryPathTextField.setBounds(50, 20, 520, 20);

        browseButton.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(MainWindowTopComponent.class, "MainWindowTopComponent.browseButton.text")); // NOI18N
        browseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonActionPerformed(evt);
            }
        });
        pathPanel.add(browseButton);
        browseButton.setBounds(580, 20, 83, 23);

        searchFileTextField.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, fileTable, org.jdesktop.beansbinding.ELProperty.create("${rowSorter}"), searchFileTextField, org.jdesktop.beansbinding.BeanProperty.create("text"), "null");
        binding.setConverter(rowSorterToStringConverter1);
        bindingGroup.addBinding(binding);

        pathPanel.add(searchFileTextField);
        searchFileTextField.setBounds(200, 60, 280, 20);

        searchFileLabel.setFont(new java.awt.Font("Tahoma", 1, 11));
        org.openide.awt.Mnemonics.setLocalizedText(searchFileLabel, org.openide.util.NbBundle.getMessage(MainWindowTopComponent.class, "MainWindowTopComponent.searchFileLabel.text")); // NOI18N
        pathPanel.add(searchFileLabel);
        searchFileLabel.setBounds(130, 60, 70, 14);

        fileTablePanel.setLayout(new java.awt.BorderLayout());

        fileTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "File Name", "File Path"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        fileTable.setToolTipText(org.openide.util.NbBundle.getMessage(MainWindowTopComponent.class, "MainWindowTopComponent.fileTable.toolTipText")); // NOI18N
        fileTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                fileTableMouseClicked(evt);
            }
        });
        fileTableScrollPane.setViewportView(fileTable);

        fileTablePanel.add(fileTableScrollPane, java.awt.BorderLayout.CENTER);

        totalFilesLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

        secondsLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addGap(187, 187, 187)
                .addComponent(totalFilesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(secondsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(288, Short.MAX_VALUE))
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(secondsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(totalFilesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(fileTablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 783, Short.MAX_VALUE)
                    .addComponent(pathPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 680, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(statusPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pathPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(fileTablePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 344, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(46, Short.MAX_VALUE))
        );

        bindingGroup.bind();
    }// </editor-fold>//GEN-END:initComponents

    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
        int showDialogStatus = fileChooser.showDialog(this, "Open");
        if (showDialogStatus == JFileChooser.APPROVE_OPTION) {
            try {
                File selectedFile = fileChooser.getSelectedFile();
                fileList.clear();
                filteredFileList.clear();
                secondsLabel.setVisible(true);
                directoryPathTextField.setText(selectedFile.getPath());
                setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                long startTime = System.currentTimeMillis();
                searchFiles = SearchFileRecursive.searchFiles(selectedFile);
                totalFilesLabel.setText("Total Files : " + searchFiles.size());
                long endTime = System.currentTimeMillis();
                long actualTime = endTime - startTime;
                long seconds = actualTime / 1000;
                secondsLabel.setText("Seconds : " + seconds);
                initTable(searchFiles);
                setCursor(null);
            } catch (Exception e) {
            }
        }
}//GEN-LAST:event_browseButtonActionPerformed

    public static synchronized MainWindowTopComponent getDefault() {
        if (instance == null) {
            instance = new MainWindowTopComponent();
        }
        return instance;
    }

    public static synchronized MainWindowTopComponent findInstance() {
        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
        if (win == null) {
            Logger.getLogger(MainWindowTopComponent.class.getName()).warning(
                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
            return getDefault();
        }
        if (win instanceof MainWindowTopComponent) {
            return (MainWindowTopComponent) win;
        }
        Logger.getLogger(MainWindowTopComponent.class.getName()).warning(
                "There seem to be multiple components with the '" + PREFERRED_ID
                + "' ID. That is a potential source of errors and unexpected behavior.");
        return getDefault();
    }

    private void fileTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_fileTableMouseClicked
        try {
            final Runtime runtime = Runtime.getRuntime();
            final int selectedRow = fileTable.getSelectedRow();
            JPopupMenu popupMenu = new JPopupMenu();
            JMenuItem openDirectoryMenuItem = new JMenuItem("Open Directory");
            JMenuItem openFileMenuItem = new JMenuItem("Open File");
            openDirectoryMenuItem.addActionListener(this);
            openFileMenuItem.addActionListener(this);
            popupMenu.add(openDirectoryMenuItem);
            popupMenu.add(openFileMenuItem);
            MouseListener mouseListener = new TablePopupListener(popupMenu, fileTable);
            fileTable.addMouseListener(mouseListener);
            openDirectoryMenuItem.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        Object filePath=fileTable.getValueAt(selectedRow, 1);
                        File file= new File(filePath.toString());
                        runtime.exec("explorer " + file.getParent());
                    } catch (IOException ex) {
                    }
                }
            });

            openFileMenuItem.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        String filePath = fileTable.getValueAt(selectedRow, 1).toString();
                        File file = new File(filePath);
                        Desktop.getDesktop().open(file);
                    } catch (IOException ex) {
                    }
                }
            });
        } catch (Exception e) {
        }
}//GEN-LAST:event_fileTableMouseClicked
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browseButton;
    private javax.swing.JLabel directoryPathLabel;
    private javax.swing.JTextField directoryPathTextField;
    private javax.swing.JTable fileTable;
    private javax.swing.JPanel fileTablePanel;
    private javax.swing.JScrollPane fileTableScrollPane;
    private javax.swing.JPanel pathPanel;
    private in.jquickfinder.models.RowSorterToStringConverter rowSorterToStringConverter1;
    private javax.swing.JLabel searchFileLabel;
    private javax.swing.JTextField searchFileTextField;
    private javax.swing.JLabel secondsLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JLabel totalFilesLabel;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

    @Override
    public void componentOpened() {
        lookupResult = Utilities.actionsGlobalContext().lookupResult(FileExtension.class);
        lookupResult.addLookupListener(this);
        resultChanged(new LookupEvent(lookupResult));
        searchFileTextField.setText("");
    }

    @Override
    public void componentClosed() {
        lookupResult.removeLookupListener(this);
    }

    void writeProperties(java.util.Properties p) {
        p.setProperty("version", "1.0");
    }

    Object readProperties(java.util.Properties p) {
        if (instance == null) {
            instance = this;
        }
        instance.readPropertiesImpl(p);
        return instance;
    }

    private void readPropertiesImpl(java.util.Properties p) {
        String version = p.getProperty("version");
    }

    private void initFileChooser() {
        fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    }

    private void initTable(Collection searchFiles) {
        for (Iterator iterator = searchFiles.iterator(); iterator.hasNext();) {
            File file = (File) iterator.next();
            fileList.add(file);
        }
        tableModel = new CustomizedTableModel(fileList);
        fileTable.setModel(tableModel);
        searchFileTextField.setText("");
    }

    private void initTable(ArrayList<File> filteredList) {
        tableModel = new CustomizedTableModel(filteredList);
        fileTable.setModel(tableModel);
        searchFileTextField.setText("");
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Open Directory")) {
        } else if (e.getActionCommand().equals("Open File")) {
        }
    }

    @Override
    protected String preferredID() {
        return PREFERRED_ID;
    }

    @Override
    public void resultChanged(LookupEvent le) {
        Collection<? extends FileExtension> allExtensions = lookupResult.allInstances();
        if (!allExtensions.isEmpty()) {
            for (FileExtension fileExtension : allExtensions) {
                filterFiles(fileExtension);
            }
        }
        initTable(filteredFileList);
        totalFilesLabel.setText("Total Files : " + filteredFileList.size());
        secondsLabel.setVisible(false);
    }

    private void filterFiles(FileExtension fileExtension) {
        filteredFileList.clear();
        String extension = fileExtension.getFileExtension();
        for (File file : fileList) {
            if (file.getPath().endsWith("." + extension)) {
                filteredFileList.add(file);
            }
        }
    }
}
